/*
 * Copyright (c) 2021 The red-star Project
 *
 * Licensed under the Apache License, version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.inyourcode.core.threads;

import com.inyourcode.core.threads.api.ExecutorFactory;
import com.inyourcode.core.threads.iml.HashExecutorFactory;
import com.inyourcode.core.threads.iml.ForkJoinPoolExecutorFactory;
import com.inyourcode.core.threads.iml.ScheduleExecutorFactory;
import com.inyourcode.core.threads.iml.ThreadPoolExecutorFactory;
import com.inyourcode.core.util.Preconditions;
import com.inyourcode.core.threads.api.CloseableExecutor;

import java.util.HashMap;
import java.util.Map;

/**
 * 线程池工具类
 * @author JackLei
 */
public class ExecutorFactoryManager {
    private static Map<ExecutorFactory.Target, ExecutorFactory> factoryMap = new HashMap<>();

    public static <T extends CloseableExecutor> T newExecutor(ExecutorFactory.Target target) {
        ExecutorFactory factory = factory(target);
        Preconditions.checkNotNull(factory, "can't find this executor factory, type: {} " + target);
        return factory.newExecutor(target);
    }

    private static ExecutorFactory factory(ExecutorFactory.Target target) {
        ExecutorFactory factory = factoryMap.get(target);
        if (factory != null) {
            return factory;
        }

        switch (target) {
            case CONSUMER:
            case POOL:
                ThreadPoolExecutorFactory poolFactory = new ThreadPoolExecutorFactory();
                factoryMap.put(target, poolFactory);
                return poolFactory;
            case PROVIDER:
            case FORk_JOIN:
                ForkJoinPoolExecutorFactory forkJoinFactory = new ForkJoinPoolExecutorFactory();
                factoryMap.put(target, forkJoinFactory);
                return forkJoinFactory;
            case SCHEDULE:
                ScheduleExecutorFactory scheduleExecutorFactory = new ScheduleExecutorFactory();
                factoryMap.put(target, scheduleExecutorFactory);
                return scheduleExecutorFactory;
            case HASH:
                HashExecutorFactory hashExecutorFactory = new HashExecutorFactory();
                factoryMap.put(target, hashExecutorFactory);
                return hashExecutorFactory;
            default:
        }

        return null;
    }
}
